import {
	checkScopeHandel,
	connectDevice,
	onBLECharacteristicValueChange,
	searchDevice
} from "./device.js";
import {
	ab2hex,
	int2hex2,
	hexToArrayBuffer,
	crc8,
	int32ToBytesBigEndian
} from './index.js';

const appStore = getApp()

/**
 * 查询等待是否有设备ID，超时15秒
 */
const founfDeviceIdAwait = () => {
	return new Promise((resolve, reject) => {
		let timeoutId;
		let isTimeout = false; // 添加一个标志位
		let isQuery = false; //是否正在查询
		console.log('查找中');

		// 定时器，15秒后超时
		timeoutId = setTimeout(() => {
			isTimeout = true; // 设置超时标志
			isQuery = false;
			console.log('查找设备ID超时');
			reject(new Error('查找设备ID超时'));
		}, 1000 * (appStore.globalData.deviceConTime || 15));

		const checkDeviceId = () => {
			if (isTimeout) {
				// 如果已经超时，直接返回，不再继续查找
				return;
			}
			
			// 如果页面不是设备详情页了说明推出了 清楚定时器相关
			let pages = getCurrentPages();
			let currentPage = pages[pages.length - 1];
			let currentPagePath = currentPage.route; // 获取当前页面路径，例如 'pages/index/index'
			let currentPageFullPath = currentPage.$page.fullPath; // 获取当前页面完整路径，包含参数，例如 'pages/index/index?id=1'
			// console.log('当前页面路径：', currentPagePath);
			// console.log('当前页面完整路径：', currentPageFullPath);
			// TODO 这个path需要替换为设备详情页的path
			if(!currentPagePath.includes('index/index')) {
				isTimeout = true; // 设置超时标志
				isQuery = false;
				clearTimeout(timeoutId);
				console.log('查找设备ID关闭已经退出页面');
				reject(new Error('查找设备ID关闭已经退出页面'));
			}

			if (appStore.globalData?.deviceBleInfo?.deviceId) {
				clearTimeout(timeoutId); // 清除定时器
				isQuery = false
				resolve(appStore.globalData?.deviceBleInfo?.deviceId);
			} else {
				//  deviceId 还没有，继续等待
				isQuery = true;
				console.log('查找中');
				setTimeout(checkDeviceId, 1000); //  每 1 秒检查一次
			}
		};

		// 立即开始查找
		checkDeviceId();
	});
};



// 发送指定
const sendCmd = async (buffer) => {
	console.log(ab2hex(buffer), 'cmd')
	await checkScopeHandel()
	// 有设备id 但没链接 说明找到设备了 可以直接链接
	if (appStore.globalData.deviceBleInfo?.deviceId && !appStore.globalData.deviceBleInfo?.isConnect) {
		await connectDevice(appStore.globalData.deviceBleInfo?.deviceId, appStore.globalData.deviceBleInfo?.mac)
	}
	// 如果没有设备id则说明还没找到设备 就开始点击交互了 此时需要等待找到设备后 在进行交互
	if (!appStore.globalData?.deviceBleInfo?.deviceId) {
		await founfDeviceIdAwait()
		await connectDevice(appStore.globalData.deviceBleInfo?.deviceId, appStore.globalData.deviceBleInfo?.mac)
	}
	return new Promise((resolve, reject) => {
		uni.writeBLECharacteristicValue({
			// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
			deviceId: appStore.globalData.deviceBleInfo?.deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId: appStore.globalData.deviceBleInfo?.serviceId,
			// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
			characteristicId: appStore.globalData.deviceBleInfo?.characteristicId,
			// 这里的value是ArrayBuffer类型
			value: buffer,
			success(res) {
				console.log('writeBLECharacteristicValue success', res.errMsg)
				resolve()
			},
			fail(res) {
				uni.showToast({
					title: '发送指令失败',
					icon: 'error'
				})
				console.log('发送指令失败', res)
				if (res.errCode == 10006) {
					// 断开了清楚缓存 
					appStore.globalData.deviceBleInfo = {
						deviceId: null,
						serviceId: null,
						isConnect: false,
						mac: null,
						characteristicId: null
					}
					uni.hideLoading()
				} else if (res.errCode == 10001) {
					// 蓝牙关闭了
					uni.showModal({
						title: '提示',
						content: '蓝牙未打开,请打开蓝牙',
						showCancel: false
					})
				}else {
					// 其他失败情况统一展示连接失败并清楚缓存
					appStore.globalData.deviceBleInfo = {
						deviceId: null,
						serviceId: null,
						isConnect: false,
						mac: null,
						characteristicId: null
					}
					uni.hideLoading()
				}
				reject(res)
			}
		})
	})
}

/**
 * 查询电表
 */
export const queryBleDevice = () => {
	return new Promise((resolve, reject) => {
		const hex = `5102`
		const instructionId = 0x51;
		const instructionParams = [0x02];
		const data = [instructionId, ...instructionParams];
		const crc = crc8(data).toString(16).padStart(2, '0').toUpperCase();
		
		console.log(`查询电表状态CRC8: ${crc}`); // 输出CRC8校验码
		
		sendCmd(hexToArrayBuffer(`${hex}${crc}`))
			.then(() => {
				uni.showLoading({
					title: "读表中..."
				})
				onBLECharacteristicValueChange().then((resObj) => {
					console.log(resObj, "resObj");
					const {
						hexStr,
						byteArray
					} = resObj;
					const hexStrUpper = hexStr.toUpperCase();
					let command = hexStrUpper.slice(0, 2); //命令字
					let code = hexStrUpper.slice(2, 4); //是否成功 00 成功 01 失败
					if(command == "51") {
						uni.hideLoading()
					}
					if (command == "51") {
						const obj = {
							du: (parseInt(hexStrUpper.slice(14, 22), 16) / 1000).toFixed(
							2), //电表剩余电量
							totalDu: (
								parseInt(hexStrUpper.slice(6, 14), 16) / 1000
							).toFixed(2), //累计用电量
							power: (parseInt(hexStrUpper.slice(22, 30), 16) / 1000).toFixed(2),
							status: parseInt(hexStrUpper.slice(46, 48), 16).toFixed(
							0), //闸门状态 1-阀开， 2-阀关
						};
						console.log(obj, "obj");
						resolve(obj);
					}
				});
			})
			.catch((e) => {
				reject(e);
				console.log("抄电表失败断开连接：", e);
			})
	});
};

/**
 * 开关闸
 * status 1-阀开， 2-阀关
 */
export const openOrCloseBleDevice = ({
	status
}) => {
	return new Promise((resolve, reject) => {
		
		const instructionId = 0x57;
		const instructionParams = [0x02, status == 1 ? 0x01 : 0x02];
		const data = [instructionId, ...instructionParams];
		const crc = crc8(data).toString(16).padStart(2, '0').toUpperCase();
		const hex = `5702${status == 1 ? "01" : "02"}${crc}`; //1-阀开， 2-阀关
		console.log(hex, "开关闸(hex)");

		sendCmd(hexToArrayBuffer(hex))
			.then(() => {
				uni.showLoading({
					title: "操作中..."
				})
				onBLECharacteristicValueChange().then((resObj) => {
					console.log(resObj, "resObj");
					const {
						hexStr,
						byteArray
					} = resObj;
					const hexStrUpper = hexStr.toUpperCase();
					let command = hexStrUpper.slice(0, 2); //命令字
					let code = hexStrUpper.slice(2, 4); //是否成功 00 成功 01 失败
					if (command == "57") {
						uni.hideLoading()
					}
					if (command == "57") {
						const obj = {
							status: parseInt(hexStrUpper.slice(4, 6), 16).toFixed(
							0), //闸门状态 1-阀开， 2-阀关
						};
						console.log(obj, "obj");
						if (obj.status == 1) {
							uni.showToast({
								title: "开闸成功！",
								icon: "success"
							})
						} else {
							uni.showToast({
								title: "关闸成功！",
								icon: "success"
							})
						}
						resolve(obj);
					}
				});
			})
			.catch((e) => {
				console.log("开关闸失败：", e);
				uni.hideLoading()
				reject(e);
			})
	});
};

/**
 * 充值
 */
export const rechargeBleDevice = ({
	du
}) => {
	return new Promise((resolve, reject) => {
		
		const instructionId = 0x45;
		const instructionParams = [0x02, ...int32ToBytesBigEndian(parseInt(int2hex2(du * 1000,8), 16))];
		const data = [instructionId, ...instructionParams];
		const crc = crc8(data).toString(16).padStart(2, '0').toUpperCase();
		
		let hex = `4502${int2hex2(du * 1000,8)}${crc}`
		
		sendCmd(hexToArrayBuffer(hex)).then(_ => {
			console.log('设置电量指令发送成功，du：' + du);
			onBLECharacteristicValueChange().then((resObj) => {
				console.log(resObj, "resObjRechargeWaterBleDevice");
				const {
					hexStr,
					byteArray
				} = resObj;
				const hexStrUpper = hexStr.toUpperCase();
				let command = hexStrUpper.slice(0, 2); //命令字
				let suscode = hexStrUpper.slice(4, 6); //是否成功 00 成功 01 失败
				if (command == "45"  && suscode =='00') {
					const obj = {};
					obj.du = (parseInt(hexStrUpper.substring(6, 14), 16) / 1000).toFixed(2)
					console.log(obj, "obj");
					console.log("设置电量成功");
					resolve(obj);
				}
			});
		}).catch(_ => {
			reject()
		})
	})
}

/**
 * 读取计量系数
 */
export const redSpeed = () => {
	return new Promise((resolve, reject) => {
		
		const instructionId = 0x55;
		const instructionParams = [0x02,0x02];
		const data = [instructionId, ...instructionParams];
		const crc = crc8(data).toString(16).padStart(2, '0').toUpperCase();
		
		console.log(`读取计量模式CRC8: ${crc}`); // 输出CRC8校验码
		
		let hex = `550202${crc}`
		
		sendCmd(hexToArrayBuffer(hex)).then(_ => {
			console.log('读取计量系数指令发送成功');
			uni.showLoading({
				title: "读取中..."
			})
			onBLECharacteristicValueChange().then((resObj) => {
				console.log(resObj, "resObjRechargeWaterBleDevice");
				const {
					hexStr,
					byteArray
				} = resObj;
				const hexStrUpper = hexStr.toUpperCase();
				let command = hexStrUpper.slice(0, 2); //命令字
				let code = hexStrUpper.slice(4, 6)
				if (command == "55" && code == '02') {
					const obj = {};
					obj.speed = parseInt(hexStrUpper.substring(8, 16), 16)
					console.log(obj, "obj");
					console.log("读取计量系数成功");
					uni.showToast({
						title: "读取成功！",
						icon: "success"
					})
					resolve(obj);
				}
			});
		}).catch(_ => {
			reject()
		}).finally(() => {
			uni.hideLoading()
		})
	})
}

/**
 * 设置计量系数
 */
export const setSpeed = ({
	speed
}) => {
	return new Promise((resolve, reject) => {
		const instructionId = 0x55;
		const instructionParams = [0x02, 0x82, ...int32ToBytesBigEndian(parseInt((speed * 1000).toString(16).padStart(8, "0"), 16))];
		const data = [instructionId, ...instructionParams];
		const crc = crc8(data).toString(16).padStart(2, '0').toUpperCase();
		
		const instructionParams2 = [0x02, 0x3e, ...int32ToBytesBigEndian(parseInt((speed * 1000).toString(16).padStart(8, "0"), 16))];
		const data2 = [instructionId, ...instructionParams2];
		const crc2 = crc8(data2).toString(16).padStart(2, '0').toUpperCase();
		
		console.log(`保存参数CRC8: ${crc}`); // 输出CRC8校验码
		console.log(`55023e${int2hex2(speed * 1000,8)}${crc2}`);
		
		
		let hex = `550282${(speed * 1000).toString(16).padStart(8, "0")}${crc}` //设置系数
		let hex2 = `55023e${int2hex2(speed * 1000,8)}${crc2}` //保存系数
		
		console.log(`设置计量模式CRC8: ${crc}`); // 输出CRC8校验码
		
		sendCmd(hexToArrayBuffer(hex)).then(_ => {
			uni.showLoading({
				title: "设置中..."
			})
			sendCmd(hexToArrayBuffer(hex2)).then(_ => {
				console.log('设置并保存计量系数指令发送成功');
				onBLECharacteristicValueChange().then((resObj) => {
					console.log(resObj, "resObjRechargeWaterBleDevice");
					const {
						hexStr,
						byteArray
					} = resObj;
					const hexStrUpper = hexStr.toUpperCase();
					let command = hexStrUpper.slice(0, 2); //命令字
					if (command == "55") {
						const obj = {};
						obj.speed = parseInt(hexStrUpper.substring(6, 14), 16)
						console.log(obj, "obj");
						console.log("设置并保存计量系数成功");
						uni.showToast({
							title: "设置成功！",
							icon: "success"
						})
						resolve(obj);
					}
				});
			})
		}).catch(_ => {
			reject()
		}).finally(() => {
			uni.hideLoading()
		})
	})
}

/**
 * 清零
 */
export const clear = () => {
 return rechargeBleDevice({du:0})
}
